#include <lua-script.h>

#define LUA_ENUM(L, name, val) \
  lua_pushlstring(L, #name, sizeof(#name)-1); \
  lua_pushnumber(L, val); \
  lua_settable(L, -3);

static LuaScript *GlobalLuaScript;

int openwars_SetTitle(lua_State *L)
{
	if (lua_gettop(L) != 1)
		return luaL_error(L, "Invalid number of arguments.");

	const char *newTitle = lua_tostring(L, -1);

	char* buff = new char[strlen(newTitle)+1];
	memcpy(buff, newTitle, strlen(newTitle)+1);

    BOOST_FOREACH(IScriptCallback it, GlobalLuaScript->onSetTitle)
        (*it)(boost::any(buff));

	delete[] buff;
    return 0;
}

int openwars_SetCurrentMouse(lua_State *L)
{
	if (lua_gettop(L) != 1)
		return luaL_error(L, "Invalid number of arguments.");

	MouseType::Type mt;
	size_t i = lua_tonumber(L, -1);
	switch((size_t)lua_tonumber(L, -1))
	{
		case  1: mt = MouseType::Arrow           ; break;
		case  2: mt = MouseType::Busy            ; break;
		case  3: mt = MouseType::Help            ; break;
		case  4: mt = MouseType::Pointer         ; break;
		case  5: mt = MouseType::Move            ; break;
		case  6: mt = MouseType::Precision       ; break;
		case  7: mt = MouseType::ResizeULBR      ; break;
		case  8: mt = MouseType::ResizeBLUR      ; break;
		case  9: mt = MouseType::ResizeHorizontal; break;
		case 10: mt = MouseType::ResizeVertical  ; break;
		case 11: mt = MouseType::Text            ; break;
		case 12: mt = MouseType::Unavailable     ; break;
		case 13: mt = MouseType::BackgroundWork  ;
		default: mt = MouseType::Arrow;
	}

    BOOST_FOREACH(IScriptCallback it, GlobalLuaScript->onSetCurrentMouse)
        (*it)(boost::any(mt));

	return 0;
}

static const luaL_reg openwars_lib[] = {
	{"SetTitle",			&openwars_SetTitle			},
	{"SetCurrentMouse",	&openwars_SetCurrentMouse	},
	{NULL, NULL}
};

void LuaScript::Initialize(void)
{
	GlobalLuaScript = this;
	L = lua_open();
	luaL_openlibs(L);
	
	luaL_openlib(L, "ow", openwars_lib, 0);

	// Push the mouse types
	LUA_ENUM(L, MouseType_Arrow				, 1 );
	LUA_ENUM(L, MouseType_Busy				, 2 );
	LUA_ENUM(L, MouseType_Help				, 3 );
	LUA_ENUM(L, MouseType_Pointer			, 4 );
	LUA_ENUM(L, MouseType_Move				, 5 );
	LUA_ENUM(L, MouseType_Precision			, 6 );
	LUA_ENUM(L, MouseType_ResizeULBR		, 7 );
	LUA_ENUM(L, MouseType_ResizeBLUR		, 8 );
	LUA_ENUM(L, MouseType_ResizeHorizontal	, 9 );
	LUA_ENUM(L, MouseType_ResizeVertical	, 10);
	LUA_ENUM(L, MouseType_Text				, 11);
	LUA_ENUM(L, MouseType_Unavailable		, 12);
	LUA_ENUM(L, MouseType_BackgroundWork	, 13);

	// Push the mouse animation types
	LUA_ENUM(L, MouseAnimation_Static		, 1 );
	LUA_ENUM(L, MouseAnimation_Loop			, 2 );
	LUA_ENUM(L, MouseAnimation_Bounce		, 3 );
}

void LuaScript::Finalize(void)
{
	lua_close(L);
}

void LuaScript::LoadScript(char *fileName)
{
	if (luaL_loadfile(L, fileName) || lua_pcall(L, 0, 0, 0))
		printf("error: %s", lua_tostring(L, -1));
}
